// --- 纹理贴图

Shader "Custom/s13_normal_map"
{
    Properties
    {
        _MainTex("Main Tex", 2D) = "white"{}
        _NormalMap("NormalMap", 2D) = "bump"{}
        
        is_use_lambert_diffuse("is_use_lambert_diffuse", Range(0,1)) = 1
        _Lambert_k("Coefficient k of Lambert", float) = 0.5

        _Gloss("Gloss", Range(5,200)) = 10
        _SpecularColor("Specular Color", Color) = (1, 1, 1, 1)
        
        is_use_halfDir("is_use_halfDir", Range(0,1)) = 1
        
        _BumpScale("_BumpScale", Float) = 1
    }
    SubShader
    {
        Pass
        {
            Tags{ "LightMode"="ForwardBase" }
            
            CGPROGRAM
            
            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _NormalMap;
            float4 _NormalMap_ST;

            float _BumpScale;

            fixed4 _SpecularColor;
            float _Lambert_k;
            fixed is_use_lambert_diffuse;
            fixed is_use_halfDir;
            half _Gloss;

            #include "Lighting.cginc"
            
            # pragma vertex vert
            # pragma fragment frag

            struct a2v
            {
                float4 vertex : POSITION;
                float4 tangent : TANGENT;  // tangent.w: 用来确定切线空间中的坐标轴的方向的
                float3 normal : NORMAL;
                float4 textcoord : TEXCOORD0;
            };

            struct v2f
            {
                float4 position: SV_POSITION;
                float3 worldNormal: TEXCOORD0;
                float4 vertex: TEXCOORD1;
                float4 uv : TEXCOORD2;  // xy: _MainTex的纹理坐标, zw: 发现贴图的纹理坐标
                float3 lightDir : TEXCOORD3;
            };

            fixed3 get_color(float4 vertex, fixed3 normalDir, fixed3 texColor, fixed3 lightDir)
            {
                const fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;

                const float half_lambert = dot(normalDir, lightDir) * _Lambert_k + _Lambert_k;
                const float all_lambert = max(dot(normalDir, lightDir), 0);
                
                fixed3 diffuse;
                if (is_use_lambert_diffuse > 0.5)
                {
                    diffuse = _LightColor0.rgb * half_lambert * texColor;
                }  
                else
                {
                    // 否则，使用_Color中定义的颜色
                    diffuse = _LightColor0.rgb * all_lambert * texColor;
                }
                
                const fixed3 reflectDir = normalize(reflect(-lightDir, normalDir));

                // --- viewDir = [camera pos in word] - [vertex pos in word]
                const fixed3 viewDir = normalize(UnityWorldSpaceViewDir(vertex));

                float cos_theta ;
                if (is_use_halfDir > 0.5)
                {
                    const fixed3 halfDir = normalize((viewDir + lightDir) / 2);
                    cos_theta = dot(normalDir, halfDir);
                }
                else
                {
                    cos_theta = dot(reflectDir, viewDir);
                }
                
                const fixed3 specular = _LightColor0.rgb * _SpecularColor.rgb * pow(max(cos_theta, 0), _Gloss);

                fixed3 color = diffuse + ambient + specular;
                return color;
            }

            v2f vert(a2v v)
            {
                v2f f;
                f.position = UnityObjectToClipPos(v.vertex);
                f.uv.xy = v.textcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
                f.uv.zw = v.textcoord.xy * _NormalMap_ST.xy + _NormalMap_ST.zw;
                f.worldNormal = UnityObjectToWorldNormal(v.normal);
                f.vertex = v.vertex;
                TANGENT_SPACE_ROTATION;
                // float3 binormal = cross( normalize(v.normal), normalize(v.tangent.xyz) ) * v.tangent.w;
                // float3x3 rotation = float3x3( v.tangent.xyz, binormal, v.normal );
                f.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex));
                return f;
            }

            float4 frag(v2f f) : SV_Target{
                // fixed3 normalDir = normalize(f.worldNormal);
                fixed4 normaColor = tex2D(_NormalMap, f.uv.zw);
                // fixed3 normalDir = normalize(normaColor.xyz * 2 - 1);  // tagentNormal
                fixed3 tagentNormal = UnpackNormal(normaColor);
                tagentNormal.xy = tagentNormal.xy * _BumpScale;
                
                fixed3 normalDir = normalize(tagentNormal);
                
                fixed3 texColor = tex2D(_MainTex, f.uv.xy);
                // fixed3 lightDir = normalize(WorldSpaceLightDir(f.vertex));  // 不使用法线贴图的情况
                fixed3 lightDir = normalize(f.lightDir);
                fixed3 tempColor = get_color(f.vertex, normalDir, texColor, lightDir);
                return fixed4(tempColor, 1);
            }
            
            ENDCG
        }
    }
    FallBack "Diffuse"
}
